/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MailServer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.StringTokenizer;

/**
 *
 * @author lailiaidi
 */
public class SmtpHandler extends Thread {

    private Socket obSocket;
    private BufferedReader obInput;
    private PrintWriter obOutput;

    public SmtpHandler(Socket obSocket) throws IOException {
        obSocket = obSocket;
        obInput = new BufferedReader(new InputStreamReader(obSocket.getInputStream()));
        obOutput = new PrintWriter(new OutputStreamWriter(obSocket.getOutputStream()), true);
    }

    @Override
    public void run() {
        println("220 SMTP Server Service Ready");
        //FAILURE 221
        try {
            do {
                String input = "";

                try {
                    input = obInput.readLine();

                    if (input == null) {
                        break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                /*
                 * Parse commands. For now we just ignore the command and say
                 * all is ok.
                 */
                StringTokenizer tokenizer = new StringTokenizer(input, " :");
                String command = "";

                command = tokenizer.nextToken().toUpperCase();

                if ((command.compareTo("HELO") == 0) || (command.compareTo("EHLO") == 0)) {
                    println("250 OK, Howdy ya'll!");
                    //ERRO 500, 501, 504, 421
                    continue;
                }
                //250

                if ((command.compareTo("MAIL") == 0) || (command.compareTo("SEND") == 0)) {
                    println("250 OK. MAIL/SEND received");
                    //Failure: 552, 451, 452
                    //Error: 500, 501, 421
                    continue;
                }
                if (command.compareTo("RCPT") == 0) {
                    println("250 OK. RCPT received");
                    //Failure: 550, 551, 552, 553, 450, 451, 452
                    //Error: 500, 501, 503, 421
                    continue;
                }

                if (command.compareTo("DATA") == 0) {
                    doCommand_DATA();
                    //Failure: 451, 554
                    //Error: 500, 501, 503, 421
                    continue;
                }

                if (command.compareTo("RSET") == 0) {
                    println("250 OK. RSET received");
                    //Error: 500, 501, 504, 421
                    continue;
                }

                if (command.compareTo("NOOP") == 0) {
                    println("250 OK. NOOP received");
                    //Error: 500, 421
                    continue;
                }
                if (command.compareTo("EXIT") == 0 || command.compareTo("BYE") == 0 || command.compareTo("QUIT") == 0) {
                    println("221 SMTP Server closing transmission channel");
                    //QUIT
                    //Error: 500
                    break;
                }
            } while (true);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                obSocket.close();
            } catch (Exception e) {
            }
        }
    }

    private void println(String s) {
        obOutput.println(s);
        obOutput.flush();

        System.out.println(s);
    }

    private void doCommand_DATA() throws IOException {
        println("354 Start mail input; end with <CRLF>.<CRLF>");
        System.out.println("Mail:");

        do {
            String input = obInput.readLine();
            if (input.equals(".")) {
                println("250 OK");
                break;
            } else {
                System.out.println(input);
            }
        } while (true);
    }

    private void closeConnection() throws IOException {
        obInput.close();
        obOutput.close();
    }
}
